import React, {PureComponent} from "react";
import {Form, Icon, Input, InputNumber, notification, Popconfirm, Select, Table, Tooltip} from "antd";
import {connect} from "react-redux";
import {paginationProps, tableProps} from "../../lib/ui";
import {
    del,
    getBaoGuanFeeByClientId,
    getBusinessCodeList, getClientList2,
    getCoach,
    getCurrencyList,
    getFeeList,
    getFollows,
    getLines,
    getMyColumns,
    getTransportType,
    modifyPart,
    openFollowChange,
    query,
    select,
    showEdit,
    updateBaoGuanFeeCount,
    updateDataSource,
    updateOrderFee,
    updateOrderOutFee,
    updateOverFee
} from "./actions";
import {query as goodsQuery} from '../goods/actions';
import {query as bgQuery} from '../bgType/actions';
import {
    getColumnSet,
    getCurrentOrganization,
    getLastFilter,
    getOpenFollow,
    getPrincipal, saveColumnSet,
    setOpenFollow
} from "../../lib/identity";
import {getLockStatus, getStatusText} from "../../lib/func";
import AddressInfo from "../../components/AddressInfo";
import NoInfo from "../../components/NoInfo";
import {getCarrierList, getClientList, organizations} from "../home/actions";
import {Resizable} from 'react-resizable';

const LAST_FILTER = "zadOrder";

const ResizeableTitle = props => {
    const {onResize, width, ...restProps} = props;

    if (!width) {
        return <th {...restProps} />;
    }
    return (
        <Resizable
            width={width}
            height={0}
            onResize={onResize}
            draggableOpts={{enableUserSelectHack: false}}
        >
            <th {...restProps} />
        </Resizable>
    );
};

const {Option} = Select;
const EditableContext = React.createContext();

const EditableRow = ({form, index, ...props}) => (
    <EditableContext.Provider value={form}>
        <tr {...props} />
    </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

class EditableCell extends React.Component {
    state = {
        editing: false
    };

    toggleEdit = () => {
        const editing = !this.state.editing;
        this.setState({editing}, () => {
            if (editing) {
                this.input.focus();
            }
        });
    };

    save = e => {
        const {record, handleSave, showTip, admin = false} = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[e.currentTarget.id]) {
                return;
            }
            this.toggleEdit();
            const owner = record.userId === getPrincipal().id;
            if (owner || admin) {
                const update = {...record, ...values};
                if (update.cabinetNumber === undefined || update.cabinetNumber === null || update.cabinetNumber.length === 0) {
                    const follows = update.followDtos || [{}];
                    follows[0].cabinetNumber = update.cabinetNumber;
                    update.followDtos = follows;
                }
                handleSave(update);
            } else {
                showTip();
            }
        });
    };

    saveStatus = (e, dataIndex) => {
        const {record, handleSave, showTip, admin = false} = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[e.currentTarget.id]) {
                return;
            }
            this.toggleEdit();
            const owner = record.userId === getPrincipal().id;
            // 只有自己或者管理员才能快速编辑
            if (owner || admin) {
                const follows = record.followDtos || [{}];
                follows[0][dataIndex] = e;
                handleSave({...record, ...values, followDtos: follows});
            } else {
                showTip();
            }
        });
    };

    renderCell = form => {
        this.form = form;
        const {children, dataIndex, record, inputType, options = [], placeholder} = this.props;
        const {editing} = this.state;
        let column;
        if (inputType === "number") {
            column = <InputNumber ref={node => (this.input = node)} onPressEnter={e => this.saveStatus(e, dataIndex)}
                                  onBlur={e => this.saveStatus(e, dataIndex)}/>;
        } else if (inputType === "select") {
            column = <Select placeholder={placeholder} ref={node => (this.input = node)} style={{width: 100}}
                             onChange={e => this.saveStatus(e, dataIndex)} allowClear={true}>
                {options.map((item, index) => (
                    <Option key={index} value={item.value}>
                        {item.label}
                    </Option>
                ))}
            </Select>;
        } else {
            column = <Input ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save}/>;
        }
        return editing ? (
            <Form.Item style={{margin: 0}}>
                {form.getFieldDecorator(dataIndex, {
                    initialValue: record[dataIndex],
                })(column)}
            </Form.Item>
        ) : (
            <div
                className="editable-cell-value-wrap"
                style={{paddingRight: 24}}
                onClick={this.toggleEdit}
            >
                {children}
            </div>
        );
    };

    render() {
        const {
            editable,
            dataIndex,
            title,
            record,
            index,
            inputType,
            handleSave,
            showTip,
            admin,
            children,
            valueField,
            labelField,
            ...restProps
        } = this.props;
        return (
            <td {...restProps}>
                {editable ? (
                    <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
                ) : (
                    children
                )}
            </td>
        );
    }
}

class List extends PureComponent {

    state = {rowId: "",
        columns: getColumnSet("zadOrder")};
    // 选中行
    onClickRow = (record) => {
        return {
            onClick: () => {
                this.setState({
                    rowId: record.id,
                });
            },
        };
    }
    setRowClassName = (record) => {
        // 自己创建的可以在列表编辑
        const owner = record.userId === getPrincipal().id;
        let className = owner ? 'editable-row' : '';
        // 已结算   #d0d0d0
        // 订单锁定   #BEBEBE
        if (record.status === "CONFIRMED" || record.settlement === "已结算" || record.outSettlement === "已结算") {
            className = className + " table-color-lock";
        } else if (record.alert) {
            // 即将发运未完成跟进   #FFAF60
            className = className + " table-color-send-no-finish";
        }
        return record.id === this.state.rowId ? 'clickRowStyl ' + className : className;
    }

    onPageChange = (page, pageSize) => {
        const {dispatch, filter} = this.props;
        dispatch(query({
            "userId": getPrincipal().id,
            "organizationId": getCurrentOrganization(), ...filter,
            page,
            pageSize
        }));
    };

    handleShowEdit = row => {
        const {dispatch} = this.props;
        dispatch(getFeeList()).then(action => {
            if (action.error !== true) {
                dispatch(showEdit(row));
                dispatch(updateOrderOutFee(row.outFeeList));
                dispatch(updateOrderFee(row.feeList));
                dispatch(updateOverFee(row));
                dispatch(getLines({...row}));
                dispatch(getBaoGuanFeeByClientId(row.clientId));
                dispatch(updateBaoGuanFeeCount(row));
                dispatch(getFollows(row.id));
                dispatch(getBusinessCodeList());
                dispatch(getClientList2(getCurrentOrganization()));
            } else {
                notification.error({
                    message: '获取费用列表失败'
                });
            }
        });
    };

    handleDelete = id => {
        const {dispatch, page, pageSize, filter} = this.props;
        dispatch(del(id)).then(() => {
            dispatch(query({
                "userId": getPrincipal().id, ...filter,
                "organizationId": getCurrentOrganization(),
                page,
                pageSize
            }));
        });
    };

    showTip = () => {
        notification.error({
            message: '不属于自己创建的订单不允许在列表维护,避免误操作。请到订单详情修改!'
        });
    };

    handleSave = row => {
        const {dispatch, dataSource} = this.props;
        const owner = (row.userId === getPrincipal().id) || getPrincipal().admin;
        if (owner) {
            if (row.status === "CONFIRMED") {
                notification.error({
                    message: '已锁定,不能修改'
                });
                return;
            }
            dispatch(modifyPart(row)).then(action => {
                if (action.error !== true) {
                    let deleteIndex = dataSource.findIndex(item => item.id === row.id);
                    dataSource.splice(deleteIndex, 1, row);
                    dispatch(updateDataSource(dataSource));
                    notification.success({
                        message: '保存成功'
                    });
                }
            });
        } else {
            this.showTip();
        }
    };

    componentWillUnmount() {
        const {dispatch} = this.props;
        dispatch(openFollowChange(false));
        setOpenFollow(false);
    }

    componentWillMount() {
        const {dispatch, page, pageSize} = this.props;
        dispatch(organizations(getPrincipal().id));
        dispatch(getMyColumns("zadOrder")).then(action => {
            if (action.error !== true) {
                let fields = getLastFilter(LAST_FILTER);
                if (fields === null || fields === undefined) {
                    fields = {};
                }
                dispatch(query({
                    ...fields,
                    "userId": getPrincipal().id,
                    "organizationId": getCurrentOrganization(),
                    page,
                    pageSize
                }));
                dispatch(goodsQuery());
                dispatch(bgQuery());
                dispatch(getClientList(getCurrentOrganization()));
                dispatch(getClientList2(getCurrentOrganization()));
                dispatch(getCarrierList(getCurrentOrganization()));
                dispatch(getCurrencyList());
                dispatch(getTransportType());
                dispatch(getCoach());
            } else {
                notification.error({
                    message: '获取自定义列失败'
                });
            }
        });
    };

    handleSelectChange = (selectedRowKeys) => {
        const {dispatch} = this.props;
        dispatch(select(selectedRowKeys));
    };

    handleResize = index => (e, {size}) => {
        console.info(index, 'index');
        this.setState(({columns}) => {
            console.info(columns, 'columns');
            const nextColumns = [...columns];
            nextColumns[index] = {
                ...nextColumns[index],
                width: size.width,
            };
            return {columns: nextColumns};
        });
    };

    components = {
        header: {
            cell: ResizeableTitle,
        },
    };

    render() {
        const {
            page,
            pageSize,
            totalElements,
            selectedRowKeys,
            dataSource,
            zadOrderColumns,
            openFollow,
            orderFollowStatus,
            columns,
            loading
        } = this.props;
        const rowSelection = {
            selectedRowKeys,
            columnWidth: '60px',
            onChange: this.handleSelectChange
        };
        const newValue = openFollow || getOpenFollow() === true || getOpenFollow() === 'true';
        const pageColumns = this.state.columns || getColumnSet("zadOrder");
        const newColumns = [];
        let isEmpty = false;
        if (columns.length === 0) {
            isEmpty = true;
        }
        if (newValue === true) {
            dataSource.forEach(item => {
                const follows = item.followDtos;
                if (follows && follows.length > 0) {
                    item.packagePic = follows[0].packagePic;
                    item.customsFile = follows[0].customsFile;
                    item.carFile = follows[0].carFile;
                    item.packageSolution = follows[0].packageSolution;
                    item.stFile = follows[0].stFile;
                    item.preOrderConfirm = follows[0].preOrderConfirm;
                    item.transportOrder = follows[0].transportOrder;
                    item.customsReleaseOrder = follows[0].customsReleaseOrder;
                    item.arriveTime = follows[0].arriveTime;
                    item.dskAtbMrn = follows[0].dskAtbMrn;
                    item.aging = follows[0].aging;
                    item.remindDate = follows[0].remindDate;
                }
            });
        }
        zadOrderColumns.forEach(column => {
            // 从pageColumns中过滤出相同的列
            const foundColumn = pageColumns.find(item => item.value === column.value) || {};
            if (columns.indexOf(column.label) >= 0 || isEmpty) {
                if ("dateTime" === column.type) {
                    newColumns.push({
                        ...column,
                        ...foundColumn,
                        title: column.label,
                        dataIndex: column.value,
                        render: text => <span>{text && text.toString().substr(0, 10)}</span>
                    });
                } else if ("number" === column.type) {
                    newColumns.push({
                        ...column,
                        ...foundColumn,
                        title: column.label,
                        dataIndex: column.value,
                        render: text => <span>{text && Number(text).toFixed(3)}</span>
                    });
                } else if ("money" === column.type) {
                    newColumns.push({
                        ...column,
                        ...foundColumn,
                        title: column.label,
                        dataIndex: column.value,
                        render: text => <span>{text && Number(text).toFixed(2)}</span>
                    });
                } else if ("status" === column.type) {
                    newColumns.push({
                        ...column,
                        ...foundColumn,
                        title: '状态',
                        dataIndex: 'status',
                        width: column.width,
                        render: text => getLockStatus(text)
                    });
                } else if ("address" === column.type) {
                    newColumns.push({
                        ...column,
                        ...foundColumn,
                        title: column.label,
                        dataIndex: column.value,
                        render: (text) => <AddressInfo {...text}/>,
                        width: column.width
                    });
                } else if ('enum' === column.type) {
                    newColumns.push({
                        ...column,
                        ...foundColumn,
                        title: column.label,
                        dataIndex: column.value,
                        render: (text) => getStatusText(text, column.dataSource),
                        width: column.width
                    });
                } else if ('list' === column.type) {
                    newColumns.push({
                        ...column,
                        ...foundColumn,
                        title: column.label,
                        dataIndex: column.value,
                        render: (text, record) => <NoInfo item={record[column.dataKey]} valueLabel={column.itemKey}/>,
                        width: column.width
                    });
                } else {
                    if (column.clickable === true) {
                        newColumns.push({
                            ...column,
                            ...foundColumn,
                            title: column.label,
                            dataIndex: column.value,
                            render: (text, record) => (
                                <a
                                    onClick={() => {
                                        this.handleShowEdit(record);
                                    }}
                                >
                                    {text}
                                </a>
                            ),
                            width: column.width
                        });
                    } else {
                        newColumns.push({
                            ...column,
                            ...foundColumn,
                            title: column.label,
                            dataIndex: column.value,
                            ellipsis: true,
                            render: text => <Tooltip placement="top" title={text}>{text}</Tooltip>
                        });
                    }
                }
            }
        });
        if (newValue === true) {
            newColumns.push(
                {
                    title: "装箱图片",
                    dataIndex: "packagePic",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "报关文件",
                    dataIndex: "customsFile",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "随车文件",
                    dataIndex: "carFile",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "装箱方案",
                    dataIndex: "packageSolution",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "ST文件",
                    dataIndex: "stFile",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "预录单确认",
                    dataIndex: "preOrderConfirm",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "运单",
                    dataIndex: "transportOrder",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "报关放行单",
                    dataIndex: "customsReleaseOrder",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "到站时间",
                    dataIndex: "arriveTime",
                    width: "160px",
                }
            );
            newColumns.push(
                {
                    title: "DSK/ATB/MRN",
                    dataIndex: "dskAtbMrn",
                    width: "130px",
                    editable: true,
                    inputType: "select",
                    placeholder: "装箱图片",
                    options: orderFollowStatus,
                }
            );
            newColumns.push(
                {
                    title: "时效",
                    dataIndex: "aging",
                    width: "130px",
                    editable: true
                }
            );
            newColumns.push(
                {
                    title: "提醒日期",
                    dataIndex: "remindDate",
                    width: "130px"
                }
            );
        }

        saveColumnSet("zadOrder", newColumns);

        const editColumns = newColumns.map((col, index) => {
            return {
                ...col,
                onCell: record => ({
                    record,
                    editable: col.editable,
                    dataIndex: col.dataIndex,
                    title: col.title,
                    options: col.options,
                    placeholder: col.placeholder,
                    inputType: col.inputType,
                    handleSave: this.handleSave,
                    showTip: this.showTip,
                    admin: getPrincipal().admin
                }),
                onHeaderCell: column => ({
                    width: column.width,
                    onResize: this.handleResize(index),
                }),
            };
        });


        if (getPrincipal().admin) {
            editColumns.push(
                {
                    title: '功能',
                    dataIndex: '',
                    key: 'x',
                    width: 50,
                    align: 'center',
                    fixed: 'right',
                    render: (text, record) => <span>
                    <Popconfirm title="确定删除此记录?" okText="是" cancelText="否"
                                onConfirm={() => this.handleDelete(record.id)}>
                        <Icon type="delete"/>
                    </Popconfirm>
                </span>,
                }
            );
        }
        const tablePagination = {
            ...paginationProps,
            total: totalElements,
            current: page,
            pageSize: pageSize,
            onShowSizeChange: (current, newSize) =>
                this.onPageChange && this.onPageChange(1, newSize),
            onChange: this.onPageChange
        };

        const resizeColumns = editColumns.map((col, index) => ({
            ...col,
            onHeaderCell: column => ({
                width: column.width,
                onResize: this.handleResize(index),
            }),
        }));

        const components = {
            header: {
                cell: ResizeableTitle
            },
            body: {
                row: EditableFormRow,
                cell: EditableCell,
            },
        };
        return (
            <Table
                {...tableProps}
                size={"small"}
                columns={editColumns}
                components={components}
                scroll={{x: 1500, y: 'calc(100vh - 480px)'}}
                pagination={tablePagination}
                rowSelection={rowSelection}
                dataSource={dataSource}
                loading={loading}
                onRow={this.onClickRow}
                rowClassName={this.setRowClassName}
            />
        );
    }
}

const
    mapStateToProps = state => {
        return {
            ...state.zadOrder.list,
            zadOrderColumns: state.common.zadOrderColumns,
            orderFollowStatus: state.common.orderFollowStatus,
            columns: state.zadOrder.columns.columns
        };
    };

export default connect(mapStateToProps)(List);
